#include "KeySearchWidget.h"
#include "Impl/KeySearch/KeySearchEdit.h"
#include "Impl/KeySearch/KeySearchResultDlg.h"
#include "Impl/KeySearch/TestSearchEngine.h"
#include "Impl/KeySearch/DefaultItemDelegate.h"
#include <QBoxLayout>
#include <QLabel>
#include <QMoveEvent>
#include <QApplication>
#include <QLibrary>
#include <QDebug>
#include <core/StyleMgr.h>
#define KEY_CHANGE_TIME_OUT 100;//100ms


KeySearchWidget::KeySearchWidget(QWidget* parent)
	:QFrame(parent)
{
	QHBoxLayout* layout = new QHBoxLayout();
	layout->setContentsMargins(0, 0, 0, 0);
	layout->setSpacing(0);
	QLabel* label = new QLabel(this);
	label->setPixmap(QPixmap(":/widgets/image/search/search_normal.png"));
	label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
	label->setFocusPolicy(Qt::FocusPolicy::ClickFocus);
	layout->addWidget(label);

	m_edit = new KeySearchEdit(this);
	label->setFocusProxy(m_edit);
	setFocusProxy(m_edit);
	layout->addWidget(m_edit);

	setLayout(layout);

	QString style= QString("KeySearchWidget{border: 0px solid #193D37; border-radius:2px; background:#%1}\n"
		"KeySearchWidget:hover{border: 0px solid #FFB000; border-radius:2px; background:#%2}")
		.arg(StyleMgr::instance().color("BackNormal").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("Hover").rgb(), 0, 16);
	setStyleSheet(style);

	m_resultDlg = new KeySearchResultDlg(this);
	m_resultDlg->hide();
	connect(this, &KeySearchWidget::resultReached, m_resultDlg, &KeySearchResultDlg::onResultReached, Qt::QueuedConnection);
	connect(m_edit, &QLineEdit::textChanged, this, &KeySearchWidget::onSearchTextChanged);

	m_delegate = new DefaultItemDelegate(this);
	setResultItemDelegate(m_delegate);
}

void KeySearchWidget::setSearchText(const QString& txt)
{
	m_edit->setText(txt);
}

void KeySearchWidget::appendSearchText(const QString& txt)
{
	m_edit->setText(m_edit->text() + txt);
}

void KeySearchWidget::setPromptText(const QString& txt)
{
	m_edit->setPlaceholderText(txt);
	m_promptText = txt;
}

void KeySearchWidget::setResultItemDelegate(QAbstractItemDelegate* itemDelegate)
{
	m_resultDlg->setListItemDelegate(itemDelegate);
}

void KeySearchWidget::setResultDlgMaxHeight(int h)
{
	m_resultDlg->setMaximumHeight(h);
}

void KeySearchWidget::setResultDlgWidth(int w)
{
	m_resultDlg->setFixedWidth(w);
}

void KeySearchWidget::setColumnsWidth(int count, ...)
{
	QVector<int> columnWidths;
	va_list vl;
	va_start(vl, count);

	for (int i = 0; i < count; ++i)
	{
		int width = va_arg(vl, int);
		columnWidths.push_back(width);
	}
	va_end(vl);
	m_delegate->setColumnWidth(columnWidths);
}

void KeySearchWidget::setSearchWhenEmpty(bool v)
{
	m_searchWhenEmpty = v;
}

void KeySearchWidget::setSearchEngine(IKeySearchEngine* se)
{
	m_searchEngine = se;
	if (m_searchEngine)
		m_searchEngine->setResultCallback(std::bind(&KeySearchWidget::onResultReach, this, std::placeholders::_1, std::placeholders::_2));
}

void KeySearchWidget::foucsChanged(bool v)
{
	if (v)
	{
		m_edit->setPlaceholderText(QString(""));
		QString style = QString("KeySearchWidget {border: 1px solid #FFB000; border-radius:2px; background:#%1}")
			.arg(StyleMgr::instance().color("BackNormal").rgb(), 0, 16);
		setStyleSheet(style);
	}
	else
	{
		m_edit->setPlaceholderText(m_promptText);
		if (m_resultDlg->isHidden())
			m_edit->clear();

		QString style = QString("KeySearchWidget {border: 0px solid #193D37; border-radius:2px; background:#%1}\n"
			"KeySearchWidget:hover{border: 0px solid #FFB000; border-radius:2px; background:#%2}")
			.arg(StyleMgr::instance().color("BackNormal").rgb(), 0, 16)
			.arg(StyleMgr::instance().color("Hover").rgb(), 0, 16);

		setStyleSheet(style);
	}
		

	emit searchFocusChanged(v);
}

void KeySearchWidget::hideResult()
{
	m_resultDlg->hide();
}

void KeySearchWidget::clearEditFocus()
{
	m_edit->clearFocus();
}

void KeySearchWidget::onResultReach(int serialNum, QJsonArray results)
{
	if (serialNum == m_searchSerialNum)
	{
		resultReached(results);
	}
}

void KeySearchWidget::onSearchTextChanged(const QString& searchKey)
{
	if (searchKey.isEmpty() && !m_searchWhenEmpty)
	{
		m_resultDlg->hide();
		return;
	}
	++m_searchSerialNum;//TODO: max int
	//TODO: add time limit?
	if (m_searchEngine)
		m_searchEngine->search(m_searchSerialNum, searchKey);

}